<?php

namespace DecoratorPattern;

/**
 * 装饰器模式的角色和职责
 * 1. 抽象组件(Component)：定义了具体组件和装饰器都需要实现的接口
 * 2. 具体组件(ConcreteComponent):就是原始对象，定义了核心的功能实现。
 * 3. 抽象装饰器基类(Decorator)：实现组件接口，内部持有一个组件对象(也就是被装饰的对象)。
 * 4. 具体装饰器(ConcreteDecorator)：继承抽象装饰器，负责给组件增加新功能
 */

// TODO 以”文本渲染增强”为例，用装饰模式实现一个支持动态添加样式的文本组件系统。

// 1. 抽象组件接口
interface Component
{
    public function render(): string;
}

// 2. 具体组件(基础组件)
class PlainText implements Component
{
    public function render(): string
    {
        return 'Hello, World!';
    }
}

// 3. 抽象装饰器基类，后续的装饰器都需要继承
abstract class Decorator implements Component
{
    protected Component $component;

    /**
     * @param Component $component
     */
    public function __construct(Component $component)
    {
        $this->component = $component;
    }
}

// 4. 具体装饰器，负责给基础组件增加功能
// 加粗
class BoldDecorator extends Decorator
{
    public function render(): string
    {
        $str = $this->component->render();
        return "<b>$str</b>";
    }
}
// 颜色
class ColorDecorator extends Decorator
{
    private string $color;

    /**
     * @param Component $component
     * @param string $color
     */
    public function __construct(Component $component, string $color)
    {
        parent::__construct($component);
        $this->color = $color;
    }

    public function render(): string
    {
        $str = $this->component->render();
        return "<span style='color: {$this->color}'>$str</span>";
    }
}

// 测试
$text = new PlainText();
$text = new BoldDecorator($text);
$text = new ColorDecorator($text, 'red');
echo "{$text->render()}";